CC          = arm-none-eabi-gcc
LD          = arm-none-eabi-ld
AR          = arm-none-eabi-ar
OBJCOPY     = arm-none-eabi-objcopy
OBJDUMP     = arm-none-eabi-objdump

TARGET_NAME      = test.bin
TARGET_ELF_NAME  = test.elf
TARGET_DIS_NAME  = test.dis
SYSTEM_LD_NAME   = ld.lds
SYSTEM_MAP_NAME  = system.map

TOP_DIR     = .
OUT_DIR     := $(TOP_DIR)/out
BOOT_DIR    := $(TOP_DIR)/arch/arm/boot/arm920t
DIV_DIR     := $(TOP_DIR)/arch/arm/div
KERNEL_DIR  := $(TOP_DIR)/kernel
INCLUDEDIR 	:= $(TOP_DIR)/include
ARCH_INC_DIR:= $(TOP_DIR)/arch/arm/include/asm
DRIVER      := $(TOP_DIR)/driver/s3c2440

TARGET      = $(OUT_DIR)/$(TARGET_NAME)
TARGET_ELF  = $(OUT_DIR)/$(TARGET_ELF_NAME)
TARGET_DIS  = $(OUT_DIR)/$(TARGET_DIS_NAME)
SYSTEM_LD   = $(BOOT_DIR)/$(SYSTEM_LD_NAME)
SYSTEM_MAP  = $(OUT_DIR)/$(SYSTEM_MAP_NAME)

CFLAGS 		:= -g -Wall -Os -Werror -ffunction-sections -fdata-sections -mcpu=arm920t -march=armv4t -msoft-float -fno-strict-aliasing
INCLUDES   	:= -I$(INCLUDEDIR)
LIBFLAGS    := -lgcc -lm -lc
LDFLAGS     := -nostartfiles
LDFLAGS     += -Wl,--gc-sections
LDFLAGS     += -Wl,-T$(SYSTEM_LD)

S_FILES_START := $(BOOT_DIR)/start.S
S_FILES_START += $(BOOT_DIR)/lowlevel_init.S
C_FILES_START := $(BOOT_DIR)/nand.c
C_FILES_START += $(BOOT_DIR)/interrupts.c
C_FILES_START += $(BOOT_DIR)/stack.c
INCLUDES   	  += -I$(BOOT_DIR)/inc
INCLUDES   	  += -I$(ARCH_INC_DIR)

C_FILES_START := $(patsubst ./%, %, ${C_FILES_START})
C_OBJS_START  := $(C_FILES_START:%.c=${OUT_DIR}/%.o)
S_FILES_START := $(patsubst ./%, %, ${S_FILES_START})
S_OBJS_START  := $(S_FILES_START:%.S=${OUT_DIR}/%.o)

C_FILES := $(KERNEL_DIR)/main.c
C_FILES += $(KERNEL_DIR)/time/sched_clock.c
C_FILES += $(KERNEL_DIR)/printf.c
S_FILES := $(DIV_DIR)/div64.S
INCLUDES   	  += -I$(INCLUDEDIR)

include $(DRIVER)/Makefile
include $(KERNEL_DIR)/seos/Makefile

C_FILES := $(patsubst ./%, %, ${C_FILES})
C_OBJS  := $(C_FILES:%.c=${OUT_DIR}/%.o)
S_FILES := $(patsubst ./%, %, ${S_FILES})
S_OBJS  := $(S_FILES:%.S=${OUT_DIR}/%.o)

OBJS += $(S_OBJS_START) $(C_OBJS_START) $(S_OBJS) $(C_OBJS)

INCLUDES := $(patsubst ./%, %, ${INCLUDES})
INCLUDES := $(patsubst %, -I%, $(patsubst -I%, %, ${INCLUDES}))

$(TARGET): $(OBJS)
	${CC} ${LDFLAGS} -Wl,-Map=$(SYSTEM_MAP) -o $(TARGET_ELF) $^ -Wl,--start-group ${LIBFLAGS} -Wl,--end-group
	${OBJCOPY} -O binary -S $(TARGET_ELF) $@
	${OBJDUMP} -D -m arm $(TARGET_ELF) > $(TARGET_DIS)

$(S_OBJS_START):$(OUT_DIR)/%.o: %.S
	@echo '$(TARGET): ${CC} $<'
	@mkdir -p $(dir $@)
	@${CC} $(INCLUDES) $(CFLAGS) -c $< -o $@

$(C_OBJS_START):$(OUT_DIR)/%.o: %.c
	@echo '$(TARGET): ${CC} $<'
	@mkdir -p $(dir $@)
	@${CC} $(INCLUDES) $(CFLAGS) -c $< -o $@

$(S_OBJS):$(OUT_DIR)/%.o: %.S
	@echo '$(TARGET): ${CC} $<'
	@mkdir -p $(dir $@)
	@${CC} $(INCLUDES) $(CFLAGS) -c $< -o $@

$(C_OBJS):$(OUT_DIR)/%.o :%.c
	@echo '$(TARGET): ${CC} $<'
	@mkdir -p $(dir $@)
	@${CC} $(INCLUDES) $(CFLAGS) -c $< -o $@

.PHONY: clean
clean:
	@rm -rf $(OUT_DIR)
	@echo clean done

.PHONY: debug
debug:
	@echo C_FILES_START = ${C_FILES_START}
	@echo C_OBJS_START  = ${C_OBJS_START}
	@echo S_FILES_START = ${S_FILES_START}
	@echo S_OBJS_START  = ${S_OBJS_START}
	@echo C_FILES = ${C_FILES}
	@echo C_OBJS  = ${C_OBJS}
	@echo S_FILES = ${S_FILES}
	@echo S_OBJS  = ${S_OBJS}
	@echo OBJS    = ${OBJS}
	@echo INCLUDES  = ${INCLUDES}
